<template>
  <div class="c-form-detail-group" aria-label="CFormDetailGroup" ref="formGroup">
    <el-form
      class="c-form"
      ref="ruleFormRef"
      :rules="formConfig?.rules"
      :model="modelVal"
      :label-width="formConfig?.labelWidth || 170"
      :label-position="formConfig?.labelPosition || 'right'"
      :disabled="readonly"
      @submit.prevent
    >
      <slot></slot>
    </el-form>
    <div class="form-op" v-if="!hiddenOp">
      <el-button type="primary" @click="handleSubmit" :loading="loading">{{
        isEdit ? '更改' : '立即创建'
      }}</el-button>
      <el-button @click="onCancel">取消</el-button>
    </div>
  </div>
</template>
<script lang="ts" setup>
import {
  nextTick,
  ref,
  withDefaults,
  defineProps,
  defineEmits,
  computed,
  provide,
  toRefs,
  onMounted,
  onBeforeUnmount,
  defineExpose
} from 'vue';
import { useRouter } from 'vue-router';
import { IFormConfig, MITT_KEY } from './form-detail';
import formMitt from '@/hooks/mybus';
interface IFormDetailGroupProps {
  modelValue: any;
  formConfig?: IFormConfig;
  hiddenOp?: boolean; // 隐藏底部操作
  isEdit?: boolean;
  loading?: boolean;
  readonly?: boolean;
}
const router = useRouter();

const props = withDefaults(defineProps<IFormDetailGroupProps>(), {
  modelValue: () => ({}),
  hiddenOp: false,
  loading: false,
  readonly: false
});
const modelVal = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    changeEvent(val);
  }
});
const formGroup = ref();
const ruleFormRef = ref();
const onCancel = () => {
  router.go(-1);
};
const emit = defineEmits(['update:modelValue', 'change', 'validate', 'validate-fail']);
const changeEvent = (value: any) => {
  emit('update:modelValue', value);
  nextTick(() => {
    emit('change', value);
  });
};

const handleSubmit = () => {
  return new Promise(resolve => {
    ruleFormRef.value?.validate((valid: boolean) => {
      if (valid) {
        emit('validate', modelVal.value);
        resolve(true);
      } else {
        emit('validate-fail', modelVal.value);
        resolve(false);
      }
    });
  });
};
const validateField = (name: string) => {
  ruleFormRef.value?.validate(name);
};
const clearValidate = (name: string) => {
  ruleFormRef.value?.clearValidate(name);
};
const addValidateEvents = () => {
  if (props.formConfig?.rules) {
    formMitt.on(MITT_KEY, (res: any) => {
      validateField(res.name);
    });
  }
};
const removeValidateEvents = () => {
  formMitt.off('c.form.validate');
};
onMounted(() => {
  addValidateEvents();
});
onBeforeUnmount(() => {
  removeValidateEvents();
});
defineExpose({
  handleSubmit,
  onCancel,
  clearValidate
});
provide('CFormDetailGroup', {
  name: 'CFormDetailGroup',
  ...toRefs(props),
  modelVal,
  changeEvent,
  validateField
});
</script>
<style lang="scss" scoped>
@use '../styles/index.scss' as *;
</style>
